package com.example.springsecurity.config;

import com.example.springsecurity.handle.MyAccessDeniedHandler;
import com.example.springsecurity.handle.MyAuthenticationSuccessHandler;
import com.example.springsecurity.handle.myAuthenticationFailureHandler;
import com.example.springsecurity.sericice.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;


@Configuration
public class SecuritityConfig extends WebSecurityConfigurerAdapter {//自定义登陆页面需要继承这个类重写configure方法

    @Autowired
   private MyAccessDeniedHandler myAccessDeniedHandler;

    @Autowired
   private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private PersistentTokenRepository persistentTokenRepository;
    //自定义登陆页面重写configure方法
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()//表单认证
                .loginProcessingUrl("/denglu")  //拦截这个请求 让其执行自定义登录逻辑
                //通过控制台的输出,发现该方法虽然在controller里有,但是并不执行 ,仅仅执行自定义的登录逻辑

                .loginPage("/testlogin")//自定义的登录页面
                //登陆成功后跳转页面必须是post请求
                .successForwardUrl("/toMain")//登陆成功的跳转页面      使用自定义handler的跳转方式需要把这个注释掉
//                .successHandler(new MyAuthenticationSuccessHandler("http://www.baidu.com")) //不能与上一句共存
                .failureForwardUrl("/toError")//登陆失败的跳转页面
//                .failureHandler(new myAuthenticationFailureHandler("/error.html")) //这种方式无需controller介入

                //自定义登录参数名
                .usernameParameter("username123")
                .passwordParameter("password123");

        http.authorizeRequests()//类似拦截器
                .antMatchers("/testlogin").permitAll()//允许通过
                .antMatchers(HttpMethod.GET,"/error.html").permitAll() //仅仅允许get方式访问,下面的regex也一样适用
//                .antMatchers("/js/**","/css/**","/images/**").permitAll()   //支持这种方式一次放通
//                .antMatchers("/**/*.png").permitAll()   //*匹配任意字符 **匹配所有目录
                .regexMatchers(".+[.]png").permitAll() //这个与上面的效果一致, .任意  +表示连接  [.]转义出一个.字符 .png结尾

                //权限控制:
//                .antMatchers("/admin1.html").hasAuthority("admin")//拥有该权限才可以访问
//                .antMatchers("/admin1.html").hasAnyAuthority( "admin","bdmin")//可以指定多个权限

                .anyRequest()//除了之前配置了的所有请求,
                .authenticated();//必须登录之后被访问

        http.csrf().disable();//关闭csrf防护


        //异常处理
        http.exceptionHandling()
                .accessDeniedHandler(myAccessDeniedHandler);

        http.rememberMe()
                //自定义登录逻辑
                .userDetailsService(userDetailsService)
                .rememberMeParameter("remember-me")//自定义参数名称
                //持久层对象,
                .tokenRepository(persistentTokenRepository)
                //设置多久不用登录,默认两周,现在设置成60秒
                .tokenValiditySeconds(60);
    }

}
